﻿using Bilibili.Common.Database;
using Bilibili.Common.Log;
using Bilibili.Common.Untils;
using Bilibili.Model.Resource;
using LibVLCSharp.Shared;
using PCLUntils.Json;
using PCLUntils.Objects;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Avalonia.BiliBili.Libs.Medias
{
    public sealed class MediaSourceAdapter : BaseSourceAdapter
    {
        private LibVLC LibVlc { get; }
        private string videoWidth;
        public string Width => videoWidth;
        private string videoHeigth;
        public string Heigth => videoHeigth;
        public MediaItem Source { get; private set; }
        public MediaSourceAdapter(LibVLC libVlc)
        {
            LibVlc = libVlc;
            MediaUrls = [];
        }
        public bool Analyze(string json, int qn)
        {
            try
            {
                var obj = json.ToJObject();
                if (obj["code"].ToInt32() == 0)
                {
                    if (GetDashItem(obj, out List<DashItem> videos, out List<DashItem> audios))
                    {
                        int codecid = 7;
                        if (SettingHelper.UseHEVC)
                            codecid = 12;
                        if (videos.IsNotEmptyArray() && audios.IsNotEmptyArray())
                        {
                            var audioDash = audios.FirstOrDefault();
                            var videoDash = videos.FirstOrDefault(x => x.Id == qn && x.Codecid == codecid);
                            if (videoDash == null && codecid == 12)
                            {
                                codecid = 7;
                                videoDash = videos.FirstOrDefault(x => x.Id == qn && x.Codecid == codecid);
                            }
                            videoDash ??= videos.OrderByDescending(x => x.Id).FirstOrDefault(x => x.Codecid == 7);
                            if (videoDash != null)
                            {
                                videoWidth = videoDash.Width;
                                videoHeigth = videoDash.Height;
                                if (CreateMpdSource(videoDash, audioDash, 0, 0, out MediaItem media))
                                    Source = media;
                                else
                                {
                                    media = new MediaItem(LibVlc, new Uri(videoDash.BaseUrl));
                                    media.AddSlave(MediaSlaveType.Audio, 4, audioDash.BaseUrl);
                                    Source = media;
                                }
                                if (audioDash != null)
                                    MediaUrls.Add(audioDash.BaseUrl);
                                MediaUrls.Add(videoDash.BaseUrl);
                                return true;
                            }
                        }
                    }
                    return true;
                }
                else
                {
                    ErrorMessage = obj["message"].ToString();
                    LogManager.Instance.LogError(ErrorMessage);
                }
            }
            catch (Exception ex)
            {
                LogManager.Instance.LogError("MediaSourceAdapter -> Analyze", ex);
            }
            return false;
        }
        private bool CreateMpdSource(DashItem videoDash, DashItem audioDash, long duration, long minBufferTime, out MediaItem media)
        {
            try
            {
                var item = new DashInfo
                {
                    AudioBandwidth = audioDash.Bandwidth,
                    AudioCodec = audioDash.Codecs,
                    AudioID = audioDash.Id.ToString(),
                    AudioUrl = audioDash.BaseUrl,
                    Duration = duration,
                    DurationMS = minBufferTime,
                    VideoBandwidth = videoDash.Bandwidth,
                    VideoCodec = videoDash.Codecs,
                    VideoID = videoDash.Id.ToString(),
                    VideoFrameRate = videoDash.FrameRate,
                    VideoHeight = videoDash.Height.ToInt32(),
                    VideoWidth = videoDash.Width.ToInt32(),
                    VideoUrl = videoDash.BaseUrl
                };
                var data = $"http://www.xiaotao2333.top:50233/api/player/generatempd?par={Uri.EscapeDataString(item.ParseJson())}";
                media = new MediaItem(LibVlc, new Uri(data));
                return true;
            }
            catch (Exception ex)
            {
                media = default;
                LogManager.Instance.LogError("CreateMpdSource", ex);
                return false;
            }
        }
    }
}